package com.errol.sync.sync.wrapper;

import com.renjia.supervise.service.log.LogService;
import com.renjia.supervise.service.sync.DataSyncService;
import com.renjia.supervise.service.sync.pojo.EntityInfo;

import java.time.LocalDate;

/**
 * 对 DataSyncService 进行灵活扩展的包装类
 * 包装类是对同步服务进行功能性扩展，原则上不应修改 source 中各个方法的实现，具体包装类优先通过重写全参数 syncData 方法来实现
 * 建议将 wrapper 类构造器的访问限制符设为 package，通过 {@link DataSyncWrapperFactory} 返回 wrapper 实例
 * 注意 wrapper bean 不应注册为 spring bean，且 wrapper 实例可以有多个，因此实例间共享变量建议由 {@link DataSyncWrapperFactory} 维护
 *
 * @author zhang xiao bin
 * @version v1.0
 * @date 2021/08/16
 * @since v
 **/
public abstract class AbsDataSyncWrapper implements DataSyncService {

    protected DataSyncService source;
    protected LogService logService;

    AbsDataSyncWrapper(DataSyncService source, LogService logService) {
        this.source = source;
        this.logService = logService;
    }

    @Override
    public <E> EntityInfo<E> getEntityInfo(Class<E> entity) {
        return source.getEntityInfo(entity);
    }

    @Override
    public <E> String generateSelectClause(EntityInfo<E> entityInfo, boolean useFieldName) {
        return source.generateSelectClause(entityInfo, useFieldName);
    }

    @Override
    public <E> String generateWhereClause(EntityInfo<E> entityInfo, LocalDate rangeLeft, LocalDate rangeRight, boolean queryNewData) {
        return source.generateWhereClause(entityInfo, rangeLeft, rangeRight, queryNewData);
    }

    @Override
    public final <E> String syncData(Class<E> entityClass) {
        return this.syncData(entityClass, null, null, true);
    }

    @Override
    public final <E> String syncData(Class<E> entityClass, LocalDate syncDate, boolean updateEditedData) {
        return this.syncData(entityClass, syncDate, null, updateEditedData);
    }

    /**
     * 子类通过重写此方法进行扩展
     *
     * @param entityClass      实体类
     * @param rangeLeft        日期区间左边界，包含
     * @param rangeRight       日期区间右边界，包含
     * @param updateEditedData true 在增量同步新增数据的同时，额外同步当天更新的数据
     * @param <E>              实体类型
     * @return null 表示同步成果，否则表示失败描述或提示信息
     */
    @Override
    public <E> String syncData(Class<E> entityClass, LocalDate rangeLeft, LocalDate rangeRight, boolean updateEditedData) {
        return source.syncData(entityClass, rangeLeft, rangeRight, updateEditedData);
    }
}
